Skip to content

Scale ISO 8601 duration fractions by their digit count - #993

Open
ckarnell wants to merge 1 commit into
python-pendulum:masterfrom
ckarnell:fix-iso8601-multi-digit-fraction
Open

Scale ISO 8601 duration fractions by their digit count#993
ckarnell wants to merge 1 commit into
python-pendulum:masterfrom
ckarnell:fix-iso8601-multi-digit-fraction

Conversation

@ckarnell

Copy link
Copy Markdown

The pure-Python ISO 8601 parser divides a fractional part by 10 whatever its length:

_days, _hours = _days.split(".")
days = int(_days)
hours = int(_hours) / 10 * HOURS_PER_DAY

So "1.25" gives int("25") / 10, which is 2.5 days instead of 0.25.

from pendulum.parsing.iso8601 import parse_iso8601

parse_iso8601("P1.25D").total_seconds()    # 302400, want 108000
parse_iso8601("PT1.25H").total_seconds()   # 12600,  want 4500
parse_iso8601("PT1.05M").total_seconds()   # 90,     want 63

Single-digit fractions are right, which is why P1.5D looks fine and hides it. The same / 10 appears for weeks, days, hours and minutes, so all four scale wrong together.

This is the fallback path, reached through PENDULUM_EXTENSIONS=0 or when the extension will not import, so the Rust parser isn't affected and gives the right answers throughout.

Dividing by 10 ** len(part) is the whole change. That's it.

The tests import parse_iso8601 directly, since parse goes through the extension and would not exercise this. P1.5D is in the table as a control: it passes either way, so the other four failing on revert is the fix and not the test. Suite is 1843 passing with PENDULUM_EXTENSIONS=0 and 1843 with the extension, up from 1838 both ways.

The pure-Python parser divided the fractional part by 10 regardless of
length, so P1.25D read as 1 day plus 60 hours. Only single-digit
fractions were correct, and the four components shared the assumption.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant